package com.demo.base.utils;

import org.springframework.util.Assert;

import java.util.Map;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 字符串插值模板
 * Created by ethan on 2016/6/22.
 */
public abstract class StringTemplate {

    private static final Pattern pattern = Pattern.compile("\\$\\{([^}]+)}");

    /**
     * 简单实现${}模板功能
     * 如${aa} cc ${bb} 其中 ${aa}, ${bb} 为占位符. 可用相关变量进行替换
     *
     * @param template            模板字符串
     * @param context             替换的变量值
     * @param keyNotExistsHandler 当context字典中找不到指定的key时处理handler
     * @return 返回替换后的字符串
     */
    public static String render(String template, Map<String, Object> context, Function<String, String> keyNotExistsHandler) {
        Assert.hasText(template, "template can not be empty");
        Assert.notNull(context, "template context can not be null");

        Matcher matcher = pattern.matcher(template);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            Object object = null;
            String key = matcher.group(1);
            if (context.containsKey(key)) {
                object = context.get(key);
            } else if (keyNotExistsHandler != null) {
                object = keyNotExistsHandler.apply(key);
            }
            //fuck java!
            String newValue = (object == null ? "" : object.toString())
                    .replaceAll("\\\\", "\\\\\\\\")
                    .replaceAll("\\$", "\\\\\\$");
            matcher.appendReplacement(sb, newValue);
        }
        matcher.appendTail(sb);
        return sb.toString();
    }
}
